<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Mars Doc</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="renderer" content="webkit">

    <link href="./css/layui.css" rel="stylesheet"/>
    <link href="./css/iconfont.css" rel="stylesheet"/>
    <link href="./css/mars-doc.css" rel="stylesheet"/>

    <script type="text/javascript" src="./jquery.min.js"></script>
    <script type="text/javascript" src="./ace/ace.js"></script>
    <script type="text/javascript" src="./ace/ext-language_tools.js"></script>
    <script type="text/javascript" src="./json5.js"></script>
    <script type="text/javascript" src="./mars-doc.js"></script>
    <script type="text/javascript" src="./sha1.js"></script>
    <style>
        .layui-table-cell{
            display:table-cell;
            vertical-align: middle;
        }
    </style>
</head>
<body>


<div class="layui-layout layui-layout-admin">

    <!-- header start -->
    <div class="layui-header layui-bg-green">
        <div class="layui-logo layui-hide-xs layui-bg-black">
            <select class="layui-select group-name" id="groupName" >
                <option value="default">default</option>
            </select>
        </div>
        <!-- 头部区域（可配合layui 已有的水平导航） -->
        <div class="layui-header-search layui-layout-right">
            <input type="text" id="search" placeholder="请输入搜索內容" autocomplete="off" class="layui-input">
        </div>
    </div>
    <!-- header end -->

    <!-- left start -->
    <div class="layui-side layui-bg-black">
        <div class="layui-side-scroll">

            <!-- 左侧导航区域（可配合layui已有的垂直导航） -->
            <ul class="layui-nav layui-nav-tree" id="leftDivId" lay-shrink="all" lay-filter="navLeft" lay-allowClose="true">

            </ul>
        </div>
    </div>
    <!-- left start -->

    <div class="layui-body">
        <div class="layui-tab layui-tab-div nav-right-top" lay-filter="rightTab" lay-allowClose="true">
            <ul class="layui-tab-title">

            </ul>
            <div class="layui-tab-content right-content-div" >

            </div>
        </div>

        <div style="padding: 15px;">
            <div class="layui-card layui-panel">

            </div>
        </div>

    </div>

</div>

<div style="display: none;" id="leftTemplate">
    {{each classList as classInfo classIndex}}
    <li class="layui-nav-item">
        <a class="" href="javascript:;">{{classInfo.description}}</a>
        {{if classInfo.methodList!=null }}
        <dl class="layui-nav-child layui-nav-child-r">
            {{each classInfo.methodList as method methodIndex }}
            <dd style="display: flex;">
                <span class="left-method">{{method.method}}</span>
                <a href="javascript:;"
                   class-uid="{{classInfo.classUId}}"
                   method-id="{{method.methodId}}"
                   method-name="{{method.description}}"
                   method-method="{{method.method}}"
                   method-path="{{method.path}}"
                >
                    {{method.description}}
                </a>
            </dd>
            {{/each}}
        </dl>
        {{/if}}
    </li>
    {{/each}}
</div>

<script type="text/html" id="rightContentTemplate">

    <div class="layui-tab layui-tab-card right-content-nav layui-tab-brief " style="margin-top: 30px;">
        <ul class="layui-tab-title right-left-nav"  style="position: fixed; margin-left: 250px;margin-top: 60px;">
            <li class="layui-this" style="border: 1px solid #eee;border-right: 0px;">文档</li>
            <li >调试</li>
        </ul>
        <div class="layui-tab-content right-left-content" style="" >
            <div class="layui-tab-item layui-show">

                <div>
                    <label class="layui-form-label-doc">接口描述:</label>
                    <div class="layui-form-static">
                        {{method.description}}
                    </div>
                </div>
                <hr>
                <div>
                    <label class="layui-form-label-doc">接口地址:</label>
                    <div class="layui-form-static">
                        {{method.path}}
                    </div>
                </div>
                <hr>
                <div>
                    <label class="layui-form-label-doc">请求方式:</label>
                    <div class="layui-form-static">
                        {{method.method}}
                    </div>
                </div>
                <hr>
                <div>
                    <label class="layui-form-label-doc">Content-Type:</label>
                    <div class="layui-form-static">
                        {{method.requestContentType}}
                    </div>
                </div>
                <hr>
                <div>
                    <label class="layui-form-label-doc">请求参数:</label>
                    <div class="layui-form-static"></div>
                </div>
                <div class="request-table-div">
                    <table lay-filter="{{method.methodUId}}requestTable" class="layui-table">
                        <thead>
                        <tr>
                            <th lay-data="{field:'name', width:'30%',templet:'#nameTemplet'}">参数名称</th>
                            <th lay-data="{field:'description',  width:'26%'}">参数说明</th>
                            <th lay-data="{field:'requestType', width:'5%'}">请求类型</th>
                            <th lay-data="{field:'required', width:'5%'}">是否必须</th>
                            <th lay-data="{field:'dataType', width:'30%'}">数据类型</th>
                            <th lay-data="{field:'example', width:'6%'}">示例值</th>
                            <th lay-data="{field:'child',hide:'true'}"></th>
                            <th lay-data="{field:'collection',hide:'true'}"></th>
                            <th lay-data="{field:'level',hide:'true'}"></th>
                        </tr>
                        </thead>
                        <tbody>
                        {{if formatRequest!=null && formatRequest.length>0}}
                        {{each formatRequest rl requestListIndex}}
                        <tr>
                            <td>{{rl.name}}</td>
                            <td>{{rl.description}}</td>
                            <td>{{rl.requestType|toLowerCase}}</td>
                            <td>{{rl.required}}</td>
                            {{if rl.collection==1}}
                                <td>{{rl.dataType}}(Array)</td>
                            {{else}}
                                <td>{{rl.dataType}}</td>
                            {{/if}}
                            <td>{{rl.example!=null?rl.example:''}}</td>
                            <td>{{rl.child}}</td>
                            <td>{{rl.collection}}</td>
                            <td>{{rl.level}}</td>
                        </tr>
                        {{/each}}
                        {{/if}}
                        </tbody>
                    </table>
                </div>
                <hr>
                <div>
                    <label class="layui-form-label-doc">响应code:</label>
                    <div class="layui-form-static"></div>
                </div>
                <div class="request-table-div">
                    <table lay-filter="{{method.methodUId}}responseCodeTable" class="layui-table">
                        <thead>
                        <tr>
                            <th lay-data="{field:'name', width:'40%'}">Code</th>
                            <th lay-data="{field:'description',  width:'60%'}">说明</th>
                        </tr>
                        </thead>
                        <tbody>
                        {{if responseCode!=null && responseCode.list!=null }}
                            {{each responseCode.list rl codeIndex}}
                                <tr>
                                    <td>{{rl.code}}</td>
                                    <td>{{rl.message}}</td>
                                </tr>
                            {{/each}}
                        {{/if}}
                        </tbody>
                    </table>
                </div>
                <hr>
                <div>
                    <label class="layui-form-label-doc">响应参数:</label>
                    <div class="layui-form-static"></div>
                </div>
                <div class="request-table-div">
                    <table lay-filter="{{method.methodUId}}responseTable" class="layui-table">
                        <thead>
                        <tr>
                            <th lay-data="{field:'name', width:'33%',templet:'#nameTemplet'}">参数名称</th>
                            <th lay-data="{field:'description',  width:'34%'}">参数说明</th>
                            <th lay-data="{field:'dataType', width:'33%'}">数据类型</th>
                            <th lay-data="{field:'child', hide:'true'}"></th>
                            <th lay-data="{field:'collection', hide:'true'}">集合</th>
                            <th lay-data="{field:'level',hide:'true'}"></th>
                        </tr>
                        </thead>
                        <tbody>
                        {{if formatResponse!=null && formatResponse.length>0}}
                        {{each formatResponse rl requestListIndex}}
                        <tr>
                            <td>{{rl.name}}</td>
                            <td>{{rl.description}}</td>
                            {{if rl.collection==1}}
                                <td>{{rl.dataType}} (Array)</td>
                            {{else}}
                                <td>{{rl.dataType}}</td>
                            {{/if}}
                            <td>{{rl.child}}</td>
                            <td>{{rl.collection}}</td>
                            <td>{{rl.level}}</td>
                        </tr>
                        {{/each}}
                        {{/if}}
                        </tbody>
                    </table>
                </div>
                <hr>
                <div>
                    <label class="layui-form-label-doc">响应示例:</label>
                    <div class="layui-form-static"></div>
                </div>

                <div class="request-table-div">
                    <div class="" id="{{ method.methodUId }}ace_editor" style="height: 100px;overflow: visible!important;" >
                    </div>
                </div>
                <hr>

            </div>
            <div class="layui-tab-item">

                <form class="layui-form" action="">

                    <div style="display: inline-flex;width: 100%;padding: 9px 0px;" >
                        <a class="layui-btn" href="javascript:;"  >{{method.method}}</a>
                        <input type="text" name="title"  autocomplete="off" id="methodPath{{method.methodUId}}" class="layui-input" value="{{method.path}}" />
                        <button class="layui-btn" lay-active="sendRequest" method-uid="{{method.methodUId}}" request-method="{{method.method}}"  type="button"> 发 送 </button>
                    </div>


                    <div style="display: inline-flex;width: 100%;padding: 9px 0px;" >

                        <input type="radio" name="{{method.methodUId}}contentType" method-uid="{{method.methodUId}}"  value="x-www-form-urlencoded" title="x-www-form-urlencoded">
                        <input type="radio" name="{{method.methodUId}}contentType" method-uid="{{method.methodUId}}"  value="form-data" title="form-data" >
                        <input type="radio" name="{{method.methodUId}}contentType" method-uid="{{method.methodUId}}"  value="raw" title="raw" >


                        <select class="form-select form-select-sm " lay-ignore id="raw{{method.methodUId}}" style="display:none;" >
                            <option value="application/json" selected>JSON(application/json)</option>
                            <option value="text">Text</option>
                            <option value="text/plain">Text(text/plain)</option>
                            <option value="application/xml">XML(application/xml)</option>
                            <option value="text/xml">XML(text/xml)</option>
                            <option value="text/html">HTML(text/html)</option>
                            <option value="application/javascript">Javascript(application/javascript)</option>
                        </select>
                    </div>



                    <div style="display: inline-flex;width: 100%;padding: 9px 0px;" >
                        <table  class="layui-table debug-request-table" lay-size="lg">
                            <thead>
                            <tr>
                                <th style="width: 3%;" ><input type="checkbox" request-checkbox-all="change" checked="checked" lay-ignore name="debugRequestCheckbox{{method.methodUId}}"  /></th>
                                <th style="width: 11%;" >参数类型</th>
                                <th style="width: 20%;" >参数名</th>
                                <th style="width: 63%;" >参数值</th>
                            </tr>
                            </thead>
                            <tbody id="debugRequestTableId{{method.methodUId}}" >
                            {{if debugRequest!=null && debugRequest.length>0}}
                            {{each debugRequest rl requestListIndex}}

                            <tr>
                                <td><input type="checkbox"  checked="checked"  lay-ignore name="debugRequestCheckbox{{method.methodUId}}"  /></td>
                                <td  >{{rl.requestType|toLowerCase}}</td>
                                <td><input type="text" class="layui-input" value="{{rl.name}}" /></td>
                                {{if rl.requestType=='BODY'}}
                                <td><textarea class="layui-textarea" rows="{{rl.jsonLine}}" placeholder="{{rl.description}}" >{{rl.jsonText}}</textarea></td>
                                {{else }}
                                    {{if rl.dataType=='file' || rl.dataType=='File' }}
                                        {{if rl.multiple=='multiple'}}
                                            <td><input type="file" class="layui-input layui-input-file"  multiple="multiple" title="{{rl.description}}" /></td>
                                        {{else}}
                                            <td><input type="file" class="layui-input layui-input-file"  title="{{rl.description}}" /></td>
                                        {{/if}}
                                    {{else}}
                                         <td><input type="text" class="layui-input" value="" placeholder="{{rl.description}}" /></td>
                                    {{/if}}
                                {{/if}}
                            </tr>

                            {{/each}}
                            {{/if}}
                            </tbody>
                        </table>

                    </div>


                    <div style="display: inline-flex;width: 100%;padding: 9px 0px;" >
                        <div class="layui-tab layui-tab-brief"  lay-filter="docDemoTabBrief" style="width: 100%;margin-bottom: 100px;position: relative!important;">
                            <ul class="layui-tab-title">
                                <li class="layui-this">响应内容</li>
                                <li>Raw</li>
                                <li>Header</li>
                                <!--<li>Curl</li>-->
                            </ul>
                            <div class="debug-response-info"  id="responseStatus{{method.methodUId}}">
                                <!--<span class="debug-span-label" style="margin-right:30px;font-weight: bold;">
                                    <div class="checkbox" style="display: inline;">
                                        <label><input id="checkboxShowDescriptionb144f10b3b5a388b4180dfbf33aa7f80" type="checkbox" checked="checked">显示说明</label>
                                    </div>
                                </span>-->
                                <span class="debug-span-label">响应码:</span>
                                <span class="debug-span-value"></span>
                                <span class="debug-span-label">耗时:</span>
                                <span class="debug-span-value">ms</span>
                                <span class="debug-span-label">大小:</span>
                                <span class="debug-span-value"></span>
                            </div>
                            <div class="layui-tab-content" style="width: 100%;">
                                <div class="layui-tab-item layui-show">
                                    <div id="debugResponseContent{{method.methodUId}}">

                                    </div>
                                </div>
                                <div class="layui-tab-item">
                                    <div contenteditable="true" class="layui-textarea div-textarea" style="height: 300px" rows="10" id="debugResponseRawContent{{method.methodUId}}"></div>
                                    <!--pre id="debugResponseRawContent{{method.methodUId}}" class="layui-code" lay-height="300px" >

                                    </pre>-->
                                </div>
                                <div class="layui-tab-item">
                                    <table class="layui-table debug-request-table"  >
                                        <thead>
                                        <tr>
                                            <th>请求头</th>
                                            <th>value</th>
                                        </tr>
                                        </thead>
                                        <tbody id="responseHeader{{method.methodUId}}">
                                        <tr>
                                            <th class="active">connection</th>
                                            <td> keep-alive</td>
                                        </tr>
                                        </tbody>
                                    </table>
                                </div>
                                <!--<div class="layui-tab-item">
                                    <code>

                                    </code>
                                </div>-->
                            </div>
                        </div>
                    </div>


                </form>

            </div>
        </div>
    </div>

</script>

<script type="text/html" id="nameTemplet">
    {{# if( d.child!='' &&  d.child!=null  && d.child!='[]' ){ }}
        {{# if(d.level>1){ }}
        <i class="padding-left-level-{{d.level}}"></i>
        {{# } }}
        <i class="layui-icon layui-icon-down"></i>
        <i class="iconfont icon-leimu "></i>
        {{d.name}}
    {{#  } else { }}
        {{# if(d.level>1){ }}
        <i class="padding-left-level-{{d.level}}"></i>
        {{# } }}
         <i class="padding-left-20"></i>
        <i class="icon iconfont icon-shuxing"></i>
        {{d.name}}
    {{#  } }}
</script>

<script type="text/html" id="responseHeaderTemplate">
    {{each list h index}}
        <tr>
            <th class="active">{{h.key}}</th>
            <td>{{h.value}}</td>
        </tr>
    {{/each}}
</script>

<script type="text/html" id="responseStatusTemplate">
    {{if responseStatus==200}}
        <span class="debug-span-label">响应码:</span>
        <span class="debug-span-value">{{responseStatus}} ok</span>
        <span class="debug-span-label">耗时:</span>
        <span class="debug-span-value">{{responseTime}}ms</span>
        <span class="debug-span-label">大小:</span>
        <span class="debug-span-value">{{responseSpace}}</span>
    {{else}}
        <span class="debug-span-label">响应码:</span>
        <span class="debug-span-value-error">{{responseStatus}}</span>
        <span class="debug-span-label">耗时:</span>
        <span class="debug-span-value-error">{{responseTime}}ms</span>
        <span class="debug-span-label">大小:</span>
        <span class="debug-span-value-error">{{responseSpace}}</span>
    {{/if}}
</script>

<script type="text/html" id="loginTemplate">
    <form class="layui-form layui-form-pane1" action="" lay-filter="first" style="width: 399px;height:200px">
        <div class="layui-form-item">
            <label class="layui-form-label">账号</label>
            <div class="layui-input-block">
                <input type="text" name="username" id="username" lay-verify="required|username" lay-reqText="请输入账号" required placeholder="账号" autocomplete="off" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">密码</label>
            <div class="layui-input-block">
                <input type="password" name="password" id="password" lay-verify="required|password" autocomplete="off" placeholder="密码" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">记住密码</label>
            <div class="layui-input-block">
                <input type="number" name="rememberDay" value="1" id="rememberDay" style="width: 255px;" autocomplete="off" placeholder="记住密码天数" class="layui-input" />
                <div class="layui-input-split layui-input-suffix" style="line-height: 34px;">天</div>
            </div>
        </div>

    </form>

</script>


<script type="text/javascript" src="./layui.js"></script>
<!--    <script type="text/javascript" src="./mars-doc.js"></script>-->
<script type="text/javascript" src="./template-web.js"></script>

<script type="text/javascript">

    template.defaults.imports.toLowerCase=function (s){
        if(s){
            return s.toLowerCase();
        }
        return "";
    }

    function json5Parse(text){
        if (common.isNotEmpty(text)){
            try {
                return JSON5.parse(text);
            }catch (e){
                log.error("json5Parse error",e)
            }
        }
        return "";
    }

    function json5Stringify(obj, replacer, space){
        if (obj!=null){
            try {
                return JSON5.stringify(obj,replacer,space);
            }catch (e){
                log.error("json5Stringify error",e)
            }
        }
        return "";
    }


    layui.use(['element', 'jquery', 'layer', 'util', 'table','form','util','code','slider'], function () {
        var element = layui.element ,
            layer = layui.layer,
            util = layui.util,
            table = layui.table,
            $ = layui.$,
            form = layui.form,
            code =  layer.code,
            slider = layui.slider;

        let responseEditorMap =new Map();

        element.on('tab(rightTab)', function (data) {
            console.log("test1:" + this, data);
        });

        form.on('radio', function(data){

            let thisVal = data.value;
            let methodUId = $(this).attr("method-uid");
            console.log(data,thisVal,$("#"+methodUId+"RawDiv"));
            if (thisVal=='raw'){
                document.getElementById("raw"+methodUId).style.display='';
            }else{
                document.getElementById("raw"+methodUId).style.display='none'
            }
        });


        util.event('lay-active',{
            sendRequest:function (){
                let $this = $(this);

                let methodUId = $(this).attr("method-uid");
                let requestMethod = $(this).attr("request-method");
                let requestPath = $(this).parent().find("[id='methodPath"+methodUId+"']").val()

                let requestContentType = $('input[name="'+methodUId+'contentType"]:checked').val()
                if (common.equalsIgnoreCase("raw",requestContentType)){
                    requestContentType = $(this).parent().parent().find("[id='raw"+methodUId+"']").val();
                }
                log.log("requestContentType:"+requestContentType)

                let headerData= {};
                let bodyData = {};
                let queryData = {};
                let formData = new FormData();

                let debugRequestTableBody = $(this).parent().parent().find("[id='debugRequestTableId"+methodUId+"']");
                let trs = debugRequestTableBody.find("tr");
                if (trs){
                    for (let i = 0; i < trs.length; i++) {
                        let tr = trs[i];
                        let checkbox = $(tr).find("input[type='checkbox']").is(':checked');
                        if (checkbox){
                            let tds = $(tr).children('td');
                            let requestType = $(tds[1]).text();
                            if (common.equalsIgnoreCase("query",requestType)){
                                let queryName = $(tds[2]).find("input").val();
                                let valueType = $(tds[3]).find("input").attr("type");
                                if (common.equalsIgnoreCase("file",valueType)){
                                    let multiple =  $(tds[3]).find("input").attr("multiple")
                                    if (common.isNotEmpty(multiple) && common.equalsIgnoreCase("multiple",multiple) ){
                                        let files = $(tds[3]).find("input")[0]
                                        if (files){
                                            $.each(files.files,function (index,file){
                                                formData.append(queryName,file);
                                            })
                                        }
                                    }else{
                                        let file =$(tds[3]).find("input")[0].files[0];
                                        formData.append(queryName,file);
                                    }
                                }else{
                                    let queryValue= $(tds[3]).find("input").val();
                                    formData.append(queryName,queryValue);
                                    queryData[queryName]=queryValue;
                                }
                            }else if (common.equalsIgnoreCase("body",requestType)){

                                let queryName = $(tds[2]).find("input").val();
                                let queryValue= $(tds[3]).find("textarea").val();
                                try {
                                    JSON5.parse(queryValue);
                                }catch (e){
                                    console.error("parseJson error");
                                    layer.msg('parse json:'+ queryValue+",失败", {icon: 2});
                                    return false;
                                }
                                bodyData = Object.assign(bodyData,JSON5.parse(queryValue));

                            }else if (common.equalsIgnoreCase("header",requestType)){
                                let queryName = $(tds[2]).find("input").val();
                                let queryValue= $(tds[3]).find("input").val();
                                headerData[queryName]=queryValue;
                            }
                            console.log(requestType);
                        }

                    }
                }

                log.log("formData:"+json5Stringify(formData)," bodyData:"+json5Stringify(bodyData)+" headerData:"+json5Stringify(headerData));

                let startDate  = (new Date()).getTime();
                let requestUrl = storage.get("group-base-url")+requestPath;
                sendRequest(requestUrl, requestMethod, requestContentType, queryData, formData, bodyData, headerData,
                    function (response, status, xhr) {
                        writeResponseStatus($this, methodUId, xhr, startDate);
                        writerResponseContent(response,$this, methodUId, xhr);
                        writeResponseHeader($this, methodUId, xhr);
                    }
                    , function (xhr, status, error) {
                        writeResponseStatus($this, methodUId, xhr, startDate)
                        writerResponseContent(null,$this, methodUId, xhr);
                        writeResponseHeader($this, methodUId, xhr);
                    }
                );
            }
        })

        function writerResponseContent(response,$this,methodUId,xhr){
            let responseText = xhr.responseText;
            if (responseText){
                let contentType=xhr.getResponseHeader("Content-Type");
                let contentDisposition=xhr.getResponseHeader("Content-Disposition");
                if (common.isNotEmpty(contentDisposition)){
                    // downloadFile(xhr,response);
                }
                log.log("response contentType"+contentType+" contentDisposition:"+contentDisposition);
                let mode = "json"
                let jsonText =responseText;
                if (jsonText){

                    try {
                        jsonText = JSON5.stringify(JSON5.parse(jsonText),null,"\t");
                    }catch (e){
                        if (common.startWith(jsonText,"<!doctype html>")){
                            mode = "html";
                        }else{
                            mode="text";
                        }
                    }
                    if (common.like(contentType,"html")){

                    }
                    let jsonLine = jsonText.split('\n').length;

                    let responseEditor = responseEditorMap.get(methodUId);
                    responseEditor.setTheme("ace/theme/xcode");
                    responseEditor.session.setMode("ace/mode/"+mode);
                    responseEditor.setOption("maxLines", jsonLine + 10);
                    responseEditor.setOption("minLines", jsonLine)
                    responseEditor.setValue(jsonText);
                    responseEditor.setReadOnly(true);
                    responseEditor.clearSelection();
                    responseEditor.resize();

                    $this.parent().parent().find("[id='debugResponseRawContent"+methodUId+"']").html(jsonText);
                }else{
                    let responseEditor = responseEditorMap.get(methodUId);
                    responseEditor.setValue('');
                    responseEditor.resize();
                    $this.parent().parent().find("[id='debugResponseRawContent"+methodUId+"']").html('');
                }

            }else{
                let responseEditor = responseEditorMap.get(methodUId);
                responseEditor.setValue('');
                responseEditor.resize();
                $this.parent().parent().find("[id='debugResponseRawContent"+methodUId+"']").html('');
            }
        }

        function downloadFile(xhr,response){
            if (common.isNotEmpty(response)){
                let responseText = response;
                let contentType=xhr.getResponseHeader("Content-Type");
                let contentDisposition=xhr.getResponseHeader("Content-Disposition");
                let fileName = contentDisposition?.substring(contentDisposition?.indexOf("=")+1,contentDisposition.length);

                let blob = new Blob([responseText], { type: contentType })
                if ('download' in document.createElement('a')) {//支持a标签download的浏览器
                    let link = document.createElement("a");
                    link.download = fileName;
                    link.style.display = "none"
                    link.href = URL.createObjectURL(blob);
                    document.body.appendChild(link);
                    link.click();//执行下载
                    URL.revokeObjectURL(link.href);//释放url
                    document.body.removeChild(link);//释放标签
                } else {
                    if (window.navigator.msSaveOrOpenBlob) {
                        window.navigator.msSaveOrOpenBlob(blob, fileName)
                    }
                }
            }

        }

        function downloadFile2(url,params){
            let $iframe = document.createElement('iframe');
            let $form = document.createElement('form');
            $iframe.setAttribute('id', 'down-file-iframe');
            $form.setAttribute('target', '_self');
            $form.setAttribute('method', 'post');
            $form.setAttribute('enctype', 'multipart/form-data');
            $form.setAttribute('accept-charset', 'UTF-8')
            $form.setAttribute('action', url);
            for (let key in params) {
                let dom = document.createElement('input');
                dom.setAttribute('type', 'hidden');
                dom.setAttribute('name', key);
                dom.setAttribute('value', params[key]);
                $form.appendChild(dom);
            }
            $iframe.appendChild($form);
            document.body.appendChild($iframe);
            $form.submit();
            $iframe.remove();
        }


        function writeResponseHeader($this,methodUId,xhr){
            let responseHeaders = xhr.getAllResponseHeaders();
            if (responseHeaders) {
                let hss = responseHeaders.split("\r\n");
                let hsList = new Array();
                for (let i = 0; i < hss.length; i++) {
                    let hs = hss[i];
                    if (hs) {
                        let key = hs.substring(0, hs.indexOf(":"));
                        let value = hs.substring(hs.indexOf(":"), hs.length);
                        hsList.push({key: key, value: value})
                    }
                }
                let hsHtml = template("responseHeaderTemplate", {list: hsList})
                $this.parent().parent().find("[id='responseHeader"+methodUId+"']").html(hsHtml);
            }
        }

        function writeResponseStatus($this,methodUId,xhr,startDate){
            let responseStatus = xhr.status;
            let endDate = (new Date()).getTime();
            let responseTime = endDate-startDate;
            let responseText = xhr.responseText;
            let responseSpace = "0B";
            if (responseText){
                responseSpace = common.getTextSpace(responseText);
            }
            let html = template("responseStatusTemplate",{responseStatus:responseStatus,responseTime:responseTime,responseSpace:responseSpace})
            $this.parent().parent().find("[id='responseStatus"+methodUId+"']").html(html);
        }



        function sendRequest(url,method,requestContentType,queryData,formData,bodyData,headers,successCallback,errorCallback){
            let loading = null;
            let config = {
                url: url,
                type: method,
                async:true,
                headers:headers,
                beforeSend: function () {
                    loading = layer.load(0, {shade: [0.5,'#fff']});
                },
                success: function(response,status,xhr) {

                    layer.close(loading);
                    successCallback(response,status,xhr);
                },error:function (xhr, status, error) {
                    layer.close(loading);
                    errorCallback(xhr,status,error);
                }
            };
            if (common.equalsIgnoreCase("x-www-form-urlencoded",requestContentType)){
                let newConfig={
                    dataType:"application/x-www-form-urlencoded",
                    data:queryData
                }
                config = $.extend(config, newConfig);
            }else if (common.equalsIgnoreCase("form-data",requestContentType)){
                let newConfig={
                    contentType:false,
                    processData:false,
                    // dataType: "application/json",
                    mimeType:"multipart/form-data",
                    data:formData
                }
                config = $.extend(config, newConfig);
            }else {
                let newConfig={
                    contentType: requestContentType,
                    data: JSON.stringify(bodyData)
                }
                config = $.extend(config, newConfig);
            }

            $.ajax(config)
        }

        util.event('request-checkbox-all',{
           change:function (){
               let name = this.name;
               if (this.checked){
                   $("input[name='"+name+"']").prop("checked",true);
               }else{
                   $("input[name='"+name+"']").removeAttr("checked");
               }
           }
        });

        element.on("nav(navLeft)", function (data) {

            let methodId = $(this).attr("method-id");
            let methodMethod = $(this).attr("method-method");
            let methodPath = $(this).attr("method-path");

            let methodUId ="M"+sha1(methodId+"#"+methodPath+methodMethod);
            if (methodUId) {


                if (existTab(methodUId)) {
                    layui.element.tabChange('rightTab', methodUId)
                } else {

                    let classUId = $(this).attr("class-uid");
                    let title = $(this).attr("method-name");
                    if (!title){
                        return;
                    }

                    let thisMethod = getMethod(classUId, methodId,methodPath,methodMethod);
                    if (thisMethod){
                        thisMethod.methodUId = methodUId;
                    }

                    let thisRequest = getRequest(methodId);
                    let thisResponse = getResponse(methodId);
                    let thisResponseCode = getResponseCode(methodId);

                    if (thisMethod) {

                        let data = {
                            method: thisMethod,
                            request: thisRequest,
                            response: thisResponse,
                            responseCode:thisResponseCode,
                            formatRequest:formatParam(thisRequest),
                            formatResponse:formatParam(thisResponse),
                            debugRequest:getDebugFormatParam(thisRequest)
                        }
                        log.log("data:", data);
                        let rightContentHtml = template("rightContentTemplate", data);
                        // console.log("rightContentHtml:", rightContentHtml);
                        layui.element.tabAdd('rightTab', {title: title, content: rightContentHtml, id: methodUId})
                        layui.element.tabChange('rightTab', methodUId);

                        $("input:radio[name='"+methodUId+"contentType'][value="+ thisMethod.requestContentType +"]").attr("checked", "true");

                        form.render();

                        initTable(methodUId + 'requestTable','sm','无参数');
                        initTable(methodUId+"responseCodeTable","sm","无配置");
                        initTable(methodUId + 'responseTable','sm','无返回值');
                        initResponseJson(thisResponse,methodUId);
                        initDebugResponseContent(thisResponse,methodUId,"debugResponseContent"+methodUId);

                    }
                }
            }
        });

        function initTable(id,size,textNone){
            table.init(id, { //转化静态表格
                limit:1000,
                size: size,
                text: {
                    none: textNone
                },
            });
        }

        function initResponseJson(thisResponse,methodUId){
            let responseJson = getResponseJson(thisResponse,methodUId);
            let jsonText = null;
            let jsonLine = 5;
            if (common.isNotEmpty(responseJson)){
                jsonText = responseJson.jsonText;
                jsonLine = responseJson.jsonLine;
            }
            let editor = ace.edit(methodUId+"ace_editor");
            if (common.isNotEmpty(jsonText) && "{}"!=jsonText){
                editor.setValue(jsonText);
            }else {
                editor.setValue("");
            }
            editor.setTheme("ace/theme/xcode");
            editor.session.setMode("ace/mode/json5");
            editor.setAutoScrollEditorIntoView(false);
            if (responseJson){
                editor.setOption("maxLines", jsonLine);
            }else{
                editor.setOption("maxLines", 5);
            }
            editor.setReadOnly(true);
            editor.clearSelection();
            editor.resize();
        }

        function initDebugResponseContent(thisResponse,methodUId,debugResponseContentId){
            let responseJson = getResponseJson(thisResponse,methodUId);
            let jsonText = null;
            let jsonLine = 5;
            if (common.isNotEmpty(responseJson)){
                jsonText = responseJson.jsonText;
                jsonLine = responseJson.jsonLine;
            }

            let editor = ace.edit(debugResponseContentId);
            if (common.isNotEmpty(jsonText)  && "{}"!=jsonText ){
                editor.setValue(jsonText);
            }else {
                editor.setValue("");
            }
            editor.setTheme("ace/theme/xcode");
            editor.session.setMode("ace/mode/json5");
            editor.setAutoScrollEditorIntoView(false);
            if (responseJson){
                editor.setOption("maxLines", jsonLine+10);
                editor.setOption("minLines", jsonLine)
            }else{
                editor.setOption("maxLines", 13);
                editor.setOption("minLines",3)
            }
            editor.setReadOnly(true);
            editor.clearSelection();
            editor.resize();
            responseEditorMap.set(methodUId,editor);
        }

        function getResponseJson(response){
            let json={};
            var child = response.list;
            if (child){
                for (let i = 0; i < child.length; i++) {
                    let item=child[i];
                    appendJson(item,json)
                }
            }

            let jsonText = json5Stringify(json, null, '\t');
            let len = jsonText.split('\n').length;
            json.jsonText= jsonText;
            json.jsonLine = len;
            return json;
        }



        function appendJson(request,json){
            if (request){

                    let child = request.child;
                    let collection = request.collection;

                    if (collection==1 && child){
                        let array = [];
                        let childJson = {}
                        $.each(child,function (index,r){
                            appendJson(r,childJson);
                        });
                        array.push(childJson);
                        json[request.name]=array;
                    }else if ((collection==null || collection==0) && child){

                        let childJson = {}
                        $.each(child,function (index,r){
                            appendJson(r,childJson);
                        });
                        json[request.name]=childJson;
                    }else{
                        if (common.like(request.dataType,"String")){

                            if (collection==1){
                                json[request.name]=[''];
                            }else{
                                json[request.name]="";
                            }
                        }else{
                            if (collection==1){
                                json[request.name]=[];
                            }else{
                                json[request.name]=0;
                            }

                        }
                    }

            }
        }


        function getMethod(classUId, methodId,methodPath,methodMethod) {
            let classList = json5Parse(storage.get("classList"));
            if (classList) {
                let classInfo = {};
                for (let i = 0; i < classList.length; i++) {
                    let clazz = classList[i];
                    if (clazz.classUId == classUId) {
                        classInfo = clazz;
                        break;
                    }
                }
                let methodInfo = {};
                if (classInfo) {
                    let methodList = classInfo.methodList;
                    if (methodList){
                        for (let j = 0; j < methodList.length; j++) {
                            let method = methodList[j];
                            if (method.methodId == methodId && method.path ==methodPath && method.method== methodMethod) {
                                methodInfo = method;
                                break;
                            }
                        }
                    }
                }
                return methodInfo;
            }
            return null;
        }

        function getRequest(methodId) {
            let requestList = json5Parse(storage.get("requestList"));
            let request = {};
            if (requestList) {
                for (let i = 0; i < requestList.length; i++) {
                    let r = requestList[i];
                    if (r.methodId == methodId) {
                        request = r;
                        break;
                    }
                }
            }
            return request;
        }

        function getResponse(methodId) {
            let responseList = json5Parse(storage.get("responseList"));
            let response = {};
            if (responseList) {
                for (let j = 0; j < responseList.length; j++) {
                    let r = responseList[j];
                    if (r.methodId == methodId) {
                        response = r;
                        break;
                    }
                }
            }
            return response;
        }
        function getResponseCode(methodId) {
            let responseCodeList = json5Parse(storage.get("responseCodeList"));
            let responseCode = {};
            if (responseCodeList) {
                for (let j = 0; j < responseCodeList.length; j++) {
                    let r = responseCodeList[j];
                    if (r.methodId == methodId) {
                        responseCode = r;
                        break;
                    }
                }
            }
            return responseCode;
        }

        function existTab(methodUId) {
            let exist = false;
            $(".nav-right-top .layui-tab-title").find("li").each(function () {
                let id = $(this).attr("lay-id");
                if (id == methodUId) {
                    exist = true;
                }
            });
            return exist;
        }


        initData(null);
        function initData(callback) {
            let username = common.formatValue($("#username").val());
            if (username){
                username = sha1(username);
            }
            let password = common.formatValue($("#password").val()) ;
            if (password){
                password = sha1(password);
            }
            let rememberDay = common.formatValue($("#rememberDay").val());

            let data=new Object();
            data.username = username;
            data.password = password;
            data.rememberDay = rememberDay;
            data.v = new Date().getTime();

            jQuery.post("./mars/api",data,function (result){
                if (result.code == 0) {

                    initJsonGroup(result.data);
                    if (callback) {
                        callback();
                    }

                } else if (result.code == -10) {

                    if (callback == null) {
                        let loginHtml = template("loginTemplate", {});
                        layer.open({
                            title: '登录',
                            scrollbar: false,
                            content: loginHtml,
                            area: 'auto',
                            yes: loginYes
                        });
                    }

                }
            },"json");

        }

        function loginYes(index, layero) {
            initData(function () {
                layer.close(index); //如果设定了yes回调，需进行手工关闭
            })
        }

        function initJsonGroup(jsonArray){
            if (jsonArray){
                let groupNameHtml = "";
                let firstJson = null;
                for (let i = 0; i < jsonArray.length; i++) {
                    let json = jsonArray[i];
                    if (json){
                        if (i==0){
                            groupNameHtml+="<option selected='selected' value='"+json.groupName+"'>"+json.groupName+"</option>"
                            firstJson = json;
                        }else{
                            groupNameHtml+="<option  value='"+json.groupName+"'>"+json.groupName+"</option>"
                        }
                    }
                }
                $("#groupName").html(groupNameHtml);
                initJSON(firstJson);
            }
        }

        function initJSON(json) {

            if (json) {
                if (json.baseUrl){
                    storage.set("group-base-url",json.baseUrl);
                }
                if (json.classList) {
                    storage.set("classList", json5Stringify(json.classList));
                }
                if (json.requestList) {
                    storage.set("requestList", json5Stringify(json.requestList) );
                }
                if (json.responseList) {
                    storage.set("responseList", json5Stringify(json.responseList));
                }
                if (json.responseCodeList) {
                    storage.set("responseCodeList", json5Stringify(json.responseCodeList));
                }
                initLeft(null);
            }
        }


        $("#search").keypress(function (even) {
            if (even.which == 13) {
                let searchInput = $("#search").val();
                initLeft(searchInput);
            }
        });


        function initLeft(searchInput) {
            let classList = json5Parse(storage.get("classList"));
            if (searchInput && classList) {
                let newClassList = new Array();
                for (let i = 0; i < classList.length; i++) {
                    let classInfo = classList[i];
                    let newMethodList = new Array();
                    if (classInfo.methodList) {
                        let methodList = classInfo.methodList;
                        for (let j = 0; j < methodList.length; j++) {
                            let methodInfo = methodList[j];
                            if (common.like(methodInfo.description, searchInput)) {
                                newMethodList.push(methodInfo);
                            }
                        }
                    }
                    if (newMethodList.length > 0) {
                        classInfo.methodList = newMethodList;
                        newClassList.push(classInfo);
                    }
                }
                classList = newClassList;
            }
            let data = {
                classList: classList
            }
            let leftHtml = template("leftTemplate", data);
            document.getElementById("leftDivId").innerHTML = leftHtml;
            parent.layui.element.render('nav');
        }


        function formatParam(request){
            let requestList = new Array();
            if (request){
                let list=request.list;
                if (list){
                    let level=1;
                    for (let i = 0; i < list.length; i++) {
                        let r = list[i];
                        r.level=level;
                        requestList.push(r);
                        getChild(requestList,level,r);
                    }
                }
            }
            return requestList;
        }

        function getChild(requestList,level,request){
            if (request.child && request.child.length>0){
                let newLevel=level+1;
                let list= request.child;
                for (let j = 0; j < list.length; j++) {
                    let r = list[j];
                    r.level=newLevel;
                    requestList.push(r);
                    getChild(requestList,newLevel,r);
                }
            }
        }

        function getDebugFormatParam(request){
            let requestList = new Array();
            if (request){
                let list=request.list;
                if (list){
                    let level=1;
                    for (let i = 0; i < list.length; i++) {
                        let r = list[i];
                        r.level=level;
                        if (common.equalsIgnoreCase(r.requestType,"body")  && r.child!=null && r.child.length>0){
                            let childJson = getDebugRequestJson(r);
                            if (childJson){
                                r.jsonText = childJson.jsonText;
                                r.jsonLine = childJson.jsonLine;
                            }
                        }
                        requestList.push(r);
                    }
                }
            }
            return requestList;
        }
        function getDebugRequestJson(response){
            let json={};
            var child = response.child;
            if (child){
                for (let i = 0; i < child.length; i++) {
                    let item=child[i];
                    appendJson(item,json)
                }
            }

            let jsonText = json5Stringify(json, null, '\t');
            let len = jsonText.split('\n').length;
            json.jsonText= jsonText;
            json.jsonLine = len;
            return json;
        }

    });


</script>
</body>
</html>